package com.MedDroid.entities;

import com.MedDroid.MainApp;
import com.MedDroid.entities.database.DatabaseField;
import com.MedDroid.entities.database.DatabaseRow;
import com.MedDroid.entities.user.DatedDouble;
import com.MedDroid.entities.user.ShotHistory;

import java.util.ArrayList;

/**
 * Created with IntelliJ IDEA.
 * User: Romen
 * Date: 19/11/13
 * Time: 9:41 PM
 * Description:
 */
public class User
{
	int UserID;
	public static final String UserIDStr = "UserID";
	long RegistrationDate;
	public static final String RegisterDateStr = "RegisterDate";
	String LoginName;
	public static final String LoginNameStr = "LoginName";
	String Password;
	public static final String PasswordStr = "Password";
	Permissions Access;
	public static final String PermissionsStr = "Permissions";
	public static final String UserAccessStr = "UserAccess";
	public static final String UserTypeStr = "UserType";

	//USER INFO
	String FirstName;
	public static final String FirstNameStr = "FirstName";
	String MiddleName;
	public static final String MiddleNameStr = "MiddleName";
	String LastName;
	public static final String LastNameStr = "LastName";
	String PhoneNumber;
	public static final String PhoneNumberStr = "PhoneNumber";
	String AddressLine;
	public static final String AddressLineStr = "AddressLine";
	String City;
	public static final String CityStr = "City";
	String Province;
	public static final String ProvinceStr = "Province";
	String Country;
	public static final String CountryStr = "Country";
	String PostalCode;
	public static final String PostalCodeStr = "PostalCode";
	String EmergencyContact;
	public static final String EmergencyContactStr = "EmergencyContact";
	String EmergencyPhoneNumber;
	public static final String EmergencyPhoneNumberStr = "EmergencyPhoneNumber";

	public static final String ShotStr = "Shot";
	public static final String CommentStr = "Comment";
	public static final String WeightStr = "Weight";
	public static final String HeightStr = "Height";
	public static final String BloodStr = "Blood";
	public static final String DateStr = "Date";
	public static final String DataStr = "Data";

	//MEDICAL INFO
	ArrayList<ShotHistory> Shots;
	ArrayList<String> Comments;

	//PLOT DATA
	ArrayList<DatedDouble> WeightHistory;
	ArrayList<DatedDouble> BloodPressureHistory;
	ArrayList<DatedDouble> HeightHistory;

	//CONSTRUCTOR
	public User()
	{
		UserID = -1;
		RegistrationDate = System.currentTimeMillis();
		LoginName = "John_Doe";
		Password = "123456";
		Access = new Permissions(Permissions.UZero);
		FirstName = "John";
		MiddleName = "Blank";
		LastName = "Doe";
		PhoneNumber = "000-000-0000";
		AddressLine = "North Pole";
		City = "Cold";
		Province = "Northwest Territories";
		Country = "Canada";
		PostalCode = "H0H0H0";
		EmergencyContact = "Santa Claus";
		EmergencyPhoneNumber = "000-000-0001";

		Shots = new ArrayList<ShotHistory>();
		Comments = new ArrayList<String>();
		WeightHistory = new ArrayList<DatedDouble>();
		BloodPressureHistory = new ArrayList<DatedDouble>();
		HeightHistory = new ArrayList<DatedDouble>();
	}

	public User(int UserID, long Time)
	{
		this.UserID = UserID;
		this.RegistrationDate = Time;
		LoginName = "John_Doe";
		Password = "123456";
		Access = new Permissions(Permissions.UZero);
		FirstName = "John";
		MiddleName = "Blank";
		LastName = "Doe";
		PhoneNumber = "000-000-0000";
		AddressLine = "North Pole";
		City = "Cold";
		Province = "Northwest Territories";
		Country = "Canada";
		PostalCode = "H0H0H0";
		EmergencyContact = "Santa Claus";
		EmergencyPhoneNumber = "000-000-0001";

		Shots = new ArrayList<ShotHistory>();
		Comments = new ArrayList<String>();
		WeightHistory = new ArrayList<DatedDouble>();
		BloodPressureHistory = new ArrayList<DatedDouble>();
		HeightHistory = new ArrayList<DatedDouble>();
	}

	//GET METHODS
	public int getUserID()
	{
		return UserID;
	}

	public String getPassword()
	{
		return Password;
	}

	public Permissions getAccess()
	{
		return Access;
	}

	public String getFirstName()
	{
		return FirstName;
	}

	public String getMiddleName()
	{
		return MiddleName;
	}

	public String getLastName()
	{
		return LastName;
	}

	public String getFullName()
	{
		return FirstName + " " + MiddleName + " " + LastName;
	}

	public String getPhoneNumber()
	{
		return PhoneNumber;
	}

	public String getAddressLine()
	{
		return AddressLine;
	}

	public String getCity()
	{
		return City;
	}

	public String getProvince()
	{
		return Province;
	}

	public String getCountry()
	{
		return Country;
	}

	public String getPostalCode()
	{
		return PostalCode;
	}

	public String getEmergencyContact()
	{
		return EmergencyContact;
	}

	public String getEmergencyPhoneNumber()
	{
		return EmergencyPhoneNumber;
	}

	public ArrayList<String> getComments()
	{
		return Comments;
	}

	public ArrayList<DatedDouble> getWeightHistory()
	{
		return WeightHistory;
	}

	//SET METHODS
	public void setSuper()
	{
		this.UserID = 0;
		this.Access = new Permissions(Permissions.USuper);
		this.LoginName = "SuperUser";
		this.Password = "1234";
	}

	public void setUserID(int UserID)
	{
		this.UserID = UserID;
	}

	public void setPermissions(Permissions P)
	{
		Access = P;
	}

	public void addUserAccess(int UserID)
	{
		Access.addUserAccess(UserID);
	}

	public void removeUserAccess(int UserID)
	{
		Access.removeUserAccess(UserID);
	}

	public void setLogin(String LoginName, String Password)
	{
		this.LoginName = LoginName;
		this.Password = Password;
	}

	public void setValues(
		String FirstName,
		String MiddleName,
		String LastName,
		String PhoneNumber,
		String AddressLine,
		String City,
		String Province,
		String Country,
		String PostalCode,
		String EmergencyContact,
		String EmergencyPhoneNumber
	)
	{
		this.FirstName = FirstName;
		this.MiddleName = MiddleName;
		this.LastName = LastName;
		this.PhoneNumber = PhoneNumber;
		this.AddressLine = AddressLine;
		this.City = City;
		this.Province = Province;
		this.Country = Country;
		this.PostalCode = PostalCode;
		this.EmergencyContact = EmergencyContact;
		this.EmergencyPhoneNumber = EmergencyPhoneNumber;
	}

	//MEDICAL HISTORY METHODS
	public void addShot(ShotHistory Shot)
	{
		Shots.add(Shot);
	}
	public void addComment(String Comment)
	{
		Comments.add(Comment);
	}

	//PLOT DATA METHODS
	public void addWeightData(DatedDouble New)
	{
		WeightHistory.add(New);
	}

	public void addBloodData(DatedDouble New)
	{
		BloodPressureHistory.add(New);
	}

	public void addHeighttData(DatedDouble New)
	{
		HeightHistory.add(New);
	}

	//CONVERT TO AND FROM ROW FORMAT
	//INCOMPLETE
	public DatabaseRow buildRow()
	{
		DatabaseRow Row = new DatabaseRow(-1,"User");
		addField(Row,UserIDStr,Integer.toString(UserID));
		addField(Row,RegisterDateStr,Long.toString(RegistrationDate));
		addField(Row,LoginNameStr,LoginName);
		addField(Row,PasswordStr,Password);
		addField(Row,PermissionsStr,Permissions.buildPermissionsString(Access));
		addField(Row,UserAccessStr,Permissions.buildUserAccessString(Access));
		addField(Row,UserTypeStr,Integer.toString(Access.getUserType()));
		addField(Row,FirstNameStr,FirstName);
		addField(Row,MiddleNameStr,MiddleName);
		addField(Row,LastNameStr,LastName);
		addField(Row,PhoneNumberStr,PhoneNumber);
		addField(Row,AddressLineStr,AddressLine);
		addField(Row,CityStr,City);
		addField(Row,ProvinceStr,Province);
		addField(Row,CountryStr,Country);
		addField(Row,PostalCodeStr,PostalCode);
		addField(Row,EmergencyContactStr,EmergencyContact);
		addField(Row,EmergencyPhoneNumberStr,EmergencyPhoneNumber);
		int i = 0;
		for (ShotHistory S : Shots)
		{
			String label = ShotStr + Integer.toString(i);
			addField(Row,label,S.getShotString());
			i++;
		}
		i = 0;
		for (String S : Comments)
		{
			String label = CommentStr + Integer.toString(i);
			addField(Row,label,S);
			i++;
		}
		i = 0;
		for (DatedDouble data : WeightHistory)
		{
			String label = WeightStr + DateStr + Integer.toString(i);
			addField(Row,label,Long.toString(data.getTime()));
			label = WeightStr + DataStr + Integer.toString(i);
			addField(Row,label,Double.toString(data.getData()));
			i++;
		}
		i = 0;
		for (DatedDouble data : BloodPressureHistory)
		{
			String label = BloodStr + DateStr + Integer.toString(i);
			addField(Row,label,Long.toString(data.getTime()));
			label = BloodStr + DataStr + Integer.toString(i);
			addField(Row,label,Double.toString(data.getData()));
			i++;
		}
		i = 0;
		for (DatedDouble data : HeightHistory)
		{
			String label = HeightStr + DateStr + Integer.toString(i);
			addField(Row,label,Long.toString(data.getTime()));
			label = HeightStr + DataStr + Integer.toString(i);
			addField(Row,label,Double.toString(data.getData()));
			i++;
		}
		return Row;
	}

	private void addField(DatabaseRow Row, String Name, String Value)
	{
		Row.addField(new DatabaseField(Name,Value));
	}

	//INCOMPLETE
	public static User buildfromRow(DatabaseRow Row)
	{
		User NewUser = new User();
		NewUser.UserID = Integer.parseInt(Row.getValue(UserIDStr));
		MainApp.log(Integer.toString(NewUser.UserID));
		NewUser.RegistrationDate = Long.parseLong(Row.getValue(RegisterDateStr));
		NewUser.LoginName = Row.getValue(LoginNameStr);
		NewUser.Password = Row.getValue(PasswordStr);
		NewUser.Access = new Permissions(Row.getValue(UserTypeStr),Row.getValue(PermissionsStr),Row.getValue(UserAccessStr));
		NewUser.FirstName = Row.getValue(FirstNameStr);
		NewUser.MiddleName = Row.getValue(MiddleNameStr);
		NewUser.LastName = Row.getValue(LastNameStr);
		NewUser.PhoneNumber = Row.getValue(PhoneNumberStr);
		NewUser.AddressLine = Row.getValue(AddressLineStr);
		NewUser.City = Row.getValue(CityStr);
		NewUser.Province = Row.getValue(ProvinceStr);
		NewUser.Country = Row.getValue(CountryStr);
		NewUser.PostalCode = Row.getValue(PostalCodeStr);
		NewUser.EmergencyContact = Row.getValue(EmergencyContactStr);
		NewUser.EmergencyPhoneNumber = Row.getValue(EmergencyPhoneNumberStr);
		int i = 0;
		boolean exists = true;
		while(exists)
		{
			String label = ShotStr + Integer.toString(i);
			DatabaseField Field = Row.getField(label);
			if (Field != null)
			{
				NewUser.addShot(ShotHistory.buildShotfromString(Field.getValue()));
			}
			else
			{
				exists = false;
			}
			i++;
		}
		i = 0;
		exists = true;
		while(exists)
		{
			String label = CommentStr + Integer.toString(i);
			DatabaseField Field = Row.getField(label);
			if (Field != null)
			{
				NewUser.addComment(Field.getValue());
			}
			else
			{
				exists = false;
			}
			i++;
		}
		i=0;
		exists = true;
		while(exists)
		{
			String label = WeightStr + DateStr + Integer.toString(i);
			String label2 = WeightStr + DataStr + Integer.toString(i);
			DatabaseField Field = Row.getField(label);
			DatabaseField Field2 = Row.getField(label2);
			if (Field != null && Field2 != null)
			{
				NewUser.addWeightData(new DatedDouble(Long.parseLong(Field.getValue()),Double.parseDouble(Field2.getValue())));
			}
			else
			{
				exists = false;
			}
			i++;
		}
		i=0;
		exists = true;
		while(exists)
		{
			String label = BloodStr + DateStr + Integer.toString(i);
			String label2 = BloodStr + DataStr + Integer.toString(i);
			DatabaseField Field = Row.getField(label);
			DatabaseField Field2 = Row.getField(label2);
			if (Field != null && Field2 != null)
			{
				NewUser.addWeightData(new DatedDouble(Long.parseLong(Field.getValue()),Double.parseDouble(Field2.getValue())));
			}
			else
			{
				exists = false;
			}
			i++;
		}
		i=0;
		exists = true;
		while(exists)
		{
			String label = HeightStr + DateStr + Integer.toString(i);
			String label2 = HeightStr + DataStr + Integer.toString(i);
			DatabaseField Field = Row.getField(label);
			DatabaseField Field2 = Row.getField(label2);
			if (Field != null && Field2 != null)
			{
				NewUser.addWeightData(new DatedDouble(Long.parseLong(Field.getValue()),Double.parseDouble(Field2.getValue())));
			}
			else
			{
				exists = false;
			}
			i++;
		}
		return NewUser;
	}
}
